feat(agent): add tool-output and V2 escalation recipient types [ACTN-10480]#1667
feat(agent): add tool-output and V2 escalation recipient types [ACTN-10480]#1667kunaluipath wants to merge 1 commit into
Conversation
3b6310b to
e7fe287
Compare
🚨 Heads up:
|
e7fe287 to
c43467d
Compare
c43467d to
be04069
Compare
There was a problem hiding this comment.
Pull request overview
This PR extends the agent escalation-recipient model surface to support V2 HITL escalation recipient flows (including tool-output-resolved recipients) and updates the Action Center task-assignment client models/services to send the new recipient variants and multi-assignee payloads. It also bumps package versions and lockfiles accordingly.
Changes:
- Add new agent escalation recipient types (Workload/RoundRobin/CustomAssignees) plus a
ToolOutputRecipientbinding for runtime-resolved assignees. - Extend Action Center task recipient modeling with
WORKLOAD/ROUND_ROBINand support multi-assigneevaluesmapped intoassigneeNamesOrEmails. - Bump
uipathanduipath-platformversions and refreshuv.lockmetadata.
Reviewed changes
Copilot reviewed 7 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/uipath/src/uipath/agent/models/agent.py | Adds new escalation recipient types and the tool-output recipient binding; adjusts union parsing strategy. |
| packages/uipath/tests/agent/models/test_agent.py | Adds deserialization tests for new recipient variants and tool-output binding behavior. |
| packages/uipath-platform/src/uipath/platform/action_center/tasks.py | Adds WORKLOAD/ROUND_ROBIN recipient types and optional values for multi-assignee payloads. |
| packages/uipath-platform/src/uipath/platform/action_center/_tasks_service.py | Updates assignment request building to emit Workload/RoundRobin criteria and forward multi-assignee values. |
| packages/uipath-platform/tests/services/test_actions_service.py | Adds tests asserting new assignment payload shapes for Workload/RoundRobin and multi-assignee values. |
| packages/uipath/pyproject.toml | Bumps uipath version and uipath-platform dependency lower bound. |
| packages/uipath-platform/pyproject.toml | Bumps uipath-platform version. |
| packages/uipath/uv.lock | Updates lock metadata and bumps editable package versions. |
| packages/uipath-platform/uv.lock | Updates lock metadata and bumps editable package version. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Note: order matters in this union — ToolOutputRecipient is listed first so payloads | ||
| # carrying `source: "toolOutput"` match it before the literal variants get a chance. | ||
| # The literal classes don't define a `source` field, so Pydantic's overlap heuristics | ||
| # pick the right class via the presence of required fields (value/displayName vs | ||
| # source/toolName/outputPath). A `Field(discriminator="type")` cannot be used here |
Adds the agent + platform models needed for the V2 HITL escalation recipient flow consumed by the langchain runtime. uipath/agent/models: - New literal recipient classes for Workload (9), RoundRobin (10), and CustomAssignees (11) matching the storage schema v50 surface. - New ToolOutputRecipient class accepting types USER_ID/GROUP_ID/WORKLOAD/ ROUND_ROBIN/CUSTOM_ASSIGNEES with source="toolOutput", toolName, outputPath fields for runtime-resolved assignees. - ToolOutputRecipient listed first in the recipient Union so payloads carrying `source` match before falling through to literal variants. uipath/platform/action_center: - TaskRecipientType gains Workload and RoundRobin members. - TaskRecipient gains an optional `values` list field for the multi-assignee assigneeNamesOrEmails payload. - _tasks_service updated to forward the new fields when present. Backwards-compatible: existing payloads without source/values parse and serialize identically. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
be04069 to
2ddb1da
Compare
🚨 Heads up:
|
|
| EMAIL = "UserEmail" | ||
| GROUP_NAME = "GroupName" | ||
| WORKLOAD = "Workload" | ||
| ROUND_ROBIN = "RoundRobin" |
There was a problem hiding this comment.
Should CustomAssignments be required as an option here?
| RoundRobinRecipient, | ||
| CustomAssigneesRecipient, | ||
| ], | ||
| Field(discriminator="type"), |
There was a problem hiding this comment.
Why the Order Matters
ToolOutputRecipient must be listed first and must keep:
source: Literal["toolOutput"]as a required field.
These two properties are the only things that make it structurally disjoint from the literal classes below it, which share the same type values (for example, both WorkloadRecipient and ToolOutputRecipient accept type=WORKLOAD).
Pydantic Parsing Behavior
Pydantic evaluates Union members left-to-right and stops at the first successful match:
- Payload with
source→ToolOutputRecipientmatches, literal class is never tried. - Payload without
source→ToolOutputRecipientfails (sourceis required), so validation falls through to the literal classes.
Why a Discriminator Cannot Be Used
A Field(discriminator="type") cannot be used because the type literals are not unique across the classes.
Critical Invariants
The following invariants must hold, otherwise silent mis-typing can occur:
ToolOutputRecipientremains the first member in theUnion.ToolOutputRecipient.sourceremains a requiredLiteral["toolOutput"].- No literal class below it gains an optional
sourcefield.
| } | ||
| ] | ||
| } | ||
| elif task_recipient.type == TaskRecipientType.WORKLOAD: |
There was a problem hiding this comment.
NIT - Can clarify here that even custom assignments will follow this criteria



Adds the agent + platform models needed for the V2 HITL escalation recipient flow consumed by the langchain runtime.
uipath/agent/models:
sourcematch before falling through to literal variants.uipath/platform/action_center:
valueslist field for the multi-assignee assigneeNamesOrEmails payload.Backwards-compatible: existing payloads without source/values parse and serialize identically.